#include "BatEnemy.h"
#include "BatNormal.h"
#include "BatAttack.h"
#include "EntityManager.h"
#include "RockFall.h"

BatEnemy::BatEnemy(AnimationPlayer* batAnims, D3DXVECTOR3 position, D3DXVECTOR3 topLeft, D3DXVECTOR3 bottomRight)
	: Entity(position, 0, "Enemy"),
	batAnims(batAnims),
	stateMachine(this),
	particle(position, D3DXVECTOR3(0, 0, 0), 1000.0f),
	topLeft(topLeft),
	bottomRight(bottomRight),
	drag(0.1f, 0.5f)
{
	ForceRegistry::add(&particle, &drag);

	stateMachine.addState("BatNormal", new BatNormal());
	stateMachine.addState("BatAttack", new BatAttack());
	stateMachine.changeState("BatNormal");
	this->setTexture(batAnims->getCurrentAnimation()->getTexture());

	// REQUIRED in snake & bat enemies.
	oldOffset = LevelManager::getCurrentLevel()->getInitOffset();
}

void BatEnemy::update(float frameTime)
{
	if (alive)
	{
		stateMachine.update(frameTime);
		particle.update(frameTime);
		position = particle.position;
		batAnims->update(frameTime);

		// Calculate the change in offset per frame.
		newOffset = LevelManager::getCurrentLevel()->getOffset();
		movement = (oldOffset - newOffset);
		oldOffset = newOffset;

		// Apply change in offset to zone bounds and enemy position.
		topLeft += movement;
		bottomRight += movement;
		setPosition(getPosition() + movement);

		// Zone limits applied to enemy.
		if (particle.position.x < topLeft.x)
			setPosition(D3DXVECTOR3(topLeft.x, particle.position.y, 0));
		if (particle.position.x > bottomRight.x)
			setPosition(D3DXVECTOR3(bottomRight.x, particle.position.y, 0));
		if (particle.position.y < topLeft.y)
			setPosition(D3DXVECTOR3(particle.position.x, topLeft.y ,0));
		if (particle.position.y > bottomRight.y)
			setPosition(D3DXVECTOR3(particle.position.x, bottomRight.y, 0));

		// Check distance to enemy and set state.
		Player* player = (Player*)EntityManager::getNamedEntities("Player")->front();
		float distance = D3DXVec3Length(&(player->getPosition() - position));
		if (distance < 200.0f)
		{
			stateMachine.changeState("BatAttack");
			batAnims->playAnimation("Attack");
			direction = this->getPosition() - player->getPosition();
			D3DXVec3Normalize(&direction, &direction);
			particle.velocity.x *= -direction.x;
		}
		else 
		{
			stateMachine.changeState("BatNormal");
			
			particle.velocity = D3DXVECTOR3(0, 0, 0);
		}

		// Check collision with player
		if (alive)
		{
			D3DSURFACE_DESC batDesc;
			texture->GetLevelDesc(0, &batDesc);
			D3DXVECTOR3 batSize((float)batDesc.Width, (float)batDesc.Height, 0);
			BoundingBox batBox = { position, batSize };
			if (player->isAlive())
			{
				D3DSURFACE_DESC playerDesc;
				player->getTexture()->GetLevelDesc(0, &playerDesc);
				D3DXVECTOR3 playerSize((float)playerDesc.Width, (float)playerDesc.Height, 0);
				BoundingBox playerBox = { player->getPosition(), playerSize };
				if (TestCollision(batBox, playerBox))
				{
					Message message(player, "Hit", 0);
					MessageHandler::sendMessage(message);
				}
			}
		}
	}
}


void BatEnemy::draw(ID3DXSprite* sprite)
{
	// Idetity matrix, as the bat does not require the texture to be filpped.
	D3DXMATRIX mat;
	D3DXMatrixTransformation2D(&mat, 0, 0, 0, 0, 0, &D3DXVECTOR2(position.x, position.y));
	
	//Now we use this transformation to draw with, we set the draw position to 0 to avoid issues
	if (alive)
		batAnims->draw(sprite, D3DXVECTOR3(0, 0, 0), mat);
}

void BatEnemy::handleMessage(Message message)
{
	// Handle message code goes here....
	if (message.message == "Die")
	{
		alive = false;
	}
}		
